package game.componentes;

import game.main.GameActivity;
import game.util.Marc;
import game.util.Vitoria;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;

public class Matriz extends View {
	private final int largura;
	private final int cell;
	private Point pontoInicial = null;
	private Point pontoFinal = null;
	private Marcou marcou;
	private float strokeWidth;
	private int padding;

	public void setMarcou(Marcou marcou) {
		this.marcou = marcou;
	}

	public Matriz(Context context, AttributeSet attrs) {
		super(context, attrs);
		largura = (int)(getLargura() * 0.8);
		cell = largura / 3;
		strokeWidth = largura * 0.03F;
		padding = (int) (largura * 0.08);
	}

	private int getLargura() {
		DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
		int width = metrics.widthPixels;
		int height = metrics.heightPixels;
		if (height < width)
			return height;
		else
			return width;
	}

	@SuppressLint("DrawAllocation")
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		drawMapa(canvas);
		drawGame(canvas);
		if (GameActivity.getVitoria() != null) {
			drawVitoria(canvas, GameActivity.getVitoria());
		}
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		this.setMeasuredDimension(largura, largura);
	}

	private void drawGame(Canvas canvas) {
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++) {
				Point point = new Point(i, j);
				if (GameActivity.getJogo()[i][j] != null) {
					if (GameActivity.getJogo()[i][j].equals(Marc.X))
						drawX(canvas, point);
					else
						drawO(canvas, point);
				}
			}
	}

	public void drawVitoria(Canvas canvas, Vitoria vitoria) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setStrokeWidth(strokeWidth * 2);
		int divCell = cell / 2;
		switch (vitoria) {
			case COLUNA1:
				canvas.drawLine(divCell, divCell, divCell, divCell + cell * 2, paint);
				break;
			case COLUNA2:
				canvas.drawLine(divCell + cell, divCell, divCell + cell, divCell + cell * 2, paint);
				break;
			case COLUNA3:
				canvas.drawLine(divCell + cell * 2, divCell, divCell + cell * 2, divCell + cell * 2, paint);
				break;
			case LINHA1:
				canvas.drawLine(divCell, divCell, divCell + cell * 2, divCell, paint);
				break;
			case LINHA2:
				canvas.drawLine(divCell, divCell + cell, divCell + cell * 2, divCell + cell, paint);
				break;
			case LINHA3:
				canvas.drawLine(divCell, divCell + cell * 2, divCell + cell * 2, divCell + cell * 2, paint);
				break;
			case DIAG_PRIN:
				canvas.drawLine(divCell, divCell, cell * 3 - divCell, cell * 3 - divCell, paint);
				break;
			case DIAG_SECU:
				canvas.drawLine(divCell, cell * 2 + divCell, cell * 2 + divCell, divCell, paint);
				break;
		}
	}

	private void drawMapa(Canvas canvas) {
		Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setStrokeWidth(strokeWidth);
		canvas.drawLine(0 * cell, 1 * cell, 3 * cell, 1 * cell, paint);
		canvas.drawLine(0 * cell, 2 * cell, 3 * cell, 2 * cell, paint);
		canvas.drawLine(1 * cell, 0 * cell, 1 * cell, 3 * cell, paint);
		canvas.drawLine(2 * cell, 0 * cell, 2 * cell, 3 * cell, paint);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		float x = event.getX();
		float y = event.getY();
		switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				if (pontoInicial != null)
					pontoFinal = null;
				pontoInicial = getCampo(x, y);
			case MotionEvent.ACTION_MOVE:
				break;
			case MotionEvent.ACTION_UP:
				if (pontoFinal != null)
					pontoInicial = null;
				pontoFinal = getCampo(x, y);
				break;
		}
		if ((pontoInicial != null && pontoFinal != null) && pontoInicial.equals(pontoFinal)) {
			if (marcou != null)
				marcou.onMark(pontoFinal);
			pontoFinal = pontoInicial = null;
			invalidate();
		}
		return true;
	}

	private Point getCampo(float x, float y) {
		int linha = 0, coluna = 0;
		if (x > cell * 2)
			linha = 2;
		else if (x > cell)
			linha = 1;

		if (y > cell * 2)
			coluna = 2;
		else if (y > cell)
			coluna = 1;
		return new Point(linha, coluna);
	}

	public interface Marcou {
		void onMark(Point point);
	}

	private void drawX(Canvas canvas, Point p) {
		Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setStrokeWidth(strokeWidth);
		paint.setARGB(255, 0, 0, 255);
		canvas.drawLine(p.x * cell + padding, p.y * cell + padding, (p.x + 1) * cell - padding, (p.y + 1) * cell - padding, paint);
		canvas.drawLine(p.x * cell + padding, (p.y + 1) * cell - padding, (p.x + 1) * cell - padding, p.y * cell + padding, paint);
	}

	private void drawO(Canvas canvas, Point p) {
		Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setARGB(255, 255, 0, 0);
		int aux = (padding - 6);
		RectF rectF = new RectF(p.x * cell + aux, p.y * cell + aux, (p.x + 1) * cell - aux, (p.y + 1) * cell - aux);
		canvas.drawOval(rectF, paint);
		paint.setARGB(255, 255, 255, 255);
		rectF.left += strokeWidth;
		rectF.top += strokeWidth;
		rectF.right -= strokeWidth;
		rectF.bottom -= strokeWidth;
		canvas.drawOval(rectF, paint);
	}
}
